Merge iostream fixes.
Signed-off-by: Mike Wray <mike.wray@hp.com>
40e9808eysqT4VNDlJFqsZB2rdg4Qw tools/xfrd/connection.c
40e9808eyXfJUi4E0C3WSgrEXqQ1sQ tools/xfrd/connection.h
40e9808eULGwffNOE4kBrAfZ9YAVMA tools/xfrd/debug.h
-411b5139tfKZfWs1LQHmwDR_wjKoxQ tools/xfrd/http.h
40e9808ePADCSKL1YgGCt2TbYPnYkw tools/xfrd/lzi_stream.c
40e9808eDNAdpF71o5teYb9DTT-PRw tools/xfrd/lzi_stream.h
40e9808eQxi0EzTcPJtosrzxEIjA-Q tools/xfrd/marshal.c
40e9808etg13xfRm0Lqd8vY-jHOoTg tools/xfrd/marshal.h
40e9808eCsmywryb036TdtRMJHDMmQ tools/xfrd/select.c
40e9808e99OcM547cKMTfmCVSoWVAw tools/xfrd/select.h
-40e9808eF3NVldqRNS5IHM8gbFAvpw tools/xfrd/xdr.c
-40e9808ezXzoRHm7pybXU69NtnjimA tools/xfrd/xdr.h
40e9808edpUtf4bJ8IbqClPJj_OvbA tools/xfrd/xen_domain.c
40e9808eHviFFIwdUKOA234uIeifjA tools/xfrd/xen_domain.h
40e9808eIFeV-MDCNyVTNt5NfMPKeQ tools/xfrd/xfrd.c
static IOStream _iostdin = {
methods: &file_methods,
data: (void*)1,
+ nofree: 1,
};
/** IOStream for stdout. */
static IOStream _iostdout = {
methods: &file_methods,
data: (void*)2,
+ nofree: 1,
};
/** IOStream for stderr. */
static IOStream _iostderr = {
methods: &file_methods,
data: (void*)3,
+ nofree: 1,
};
/** IOStream for stdin. */
*/
static int file_close(IOStream *s){
int result = 0;
- if (s->data){
- result = fclose(get_file(s));
- s->data = (void*)0;
- }
+ result = fclose(get_file(s));
return result;
}
* @param s file stream
*/
static void file_free(IOStream *s){
- file_close(s);
+ // Nothing extra to do - close did it all.
}
/** Create an IOStream for a stream.
IOStream *file_stream_new(FILE *f){
IOStream *io = ALLOCATE(IOStream);
if(io){
- io->methods = &file_methods;
- io->data = (void*)f;
+ io->methods = &file_methods;
+ io->data = (void*)f;
}
return io;
}
IOStream *io = 0;
FILE *fin = fopen(file, flags);
if(fin){
- io = file_stream_new(fin);
- if(!io){
- fclose(fin);
- }
+ io = file_stream_new(fin);
+ if(!io){
+ fclose(fin);
+ }
}
return io;
}
FILE *fin = fdopen(fd, flags);
if(fin){
io = file_stream_new(fin);
- if(!io)
+ if(!io){
fclose(fin);
+ }
}
return io;
}
/** Methods used by a gzFile* IOStream. */
static const IOMethods gzip_methods = {
- read: gzip_read,
+ read: gzip_read,
write: gzip_write,
error: gzip_error,
close: gzip_close,
*/
static int gzip_close(IOStream *s){
int result = 0;
- if (s->data){
- result = gzclose(get_gzfile(s));
- s->data = (void*)0;
- }
+ result = gzclose(get_gzfile(s));
return result;
}
* @param s gzip stream
*/
static void gzip_free(IOStream *s){
- gzip_close(s);
+ // Nothing to do - close did it all.
}
/** Create an IOStream for a gzip stream.
IOStream *gzip_stream_new(gzFile *f){
IOStream *io = ALLOCATE(IOStream);
if(io){
- io->methods = &gzip_methods;
- io->data = (void*)f;
+ io->methods = &gzip_methods;
+ io->data = (void*)f;
}
return io;
}
#include "allocate.h"
-/** End of input return value. */
+/** End of input return value (for getc). */
#define IOSTREAM_EOF -1
/** An input/output abstraction.
int written;
/** Number of bytes read. */
int read;
+ /** Flag indicating whether not to free when closed. */
+ int nofree;
};
static inline int IOStream_read(IOStream *stream, void *buf, size_t n){
int result;
if(stream->closed){
- result = IOSTREAM_EOF;
+ result = -EIO;
goto exit;
}
if(!stream->methods || !stream->methods->read){
static inline int IOStream_write(IOStream *stream, const void *buf, size_t n){
int result;
if(stream->closed){
- result = IOSTREAM_EOF;
+ result = -EIO;
goto exit;
}
if(!stream->methods || !stream->methods->write){
/** Flush the stream.
*
* @param stream stream
- * @return 0 on success, IOSTREAM_EOF otherwise
+ * @return 0 on success, negative error code otherwise
*/
static inline int IOStream_flush(IOStream *stream){
int result = 0;
if(stream->closed){
- result = IOSTREAM_EOF;
+ result = -EIO;
} else if(stream->methods->flush){
result = (stream->methods->flush)(stream);
- if(result < 0) result = IOSTREAM_EOF;
}
return result;
}
/** Close the stream.
*
* @param stream to close
- * @return 1 for error, 0 otherwise
+ * @return 0 on success, negative error code otherwise
*/
static inline int IOStream_close(IOStream *stream){
- int err = 1;
+ int err = 0;
+ if(!stream || stream->closed){
+ err = -EIO;
+ goto exit;
+ }
if(stream->methods && stream->methods->close){
err = (stream->methods->close)(stream);
stream->closed = 1;
}
+ if(stream->nofree) goto exit;
+ if(stream->methods && stream->methods->free){
+ (stream->methods->free)(stream);
+ }
+ *stream = (IOStream){};
+ deallocate(stream);
+ exit:
return err;
}
return stream->closed;
}
-/** Free the memory used by the stream.
- *
- * @param stream to free
- */
-static inline void IOStream_free(IOStream *stream){
- if(!stream->closed && stream->methods && stream->methods->close){
- (stream->methods->close)(stream);
- }
- if(stream->methods && stream->methods->free){
- (stream->methods->free)(stream);
- }
- *stream = (IOStream){};
- deallocate(stream);
-}
-
-
/** Print a character to a stream, like fputc().
*
* @param stream to print to
/** Methods for a kernel stream. Output only. */
static const IOMethods kernel_methods = {
- write: kernel_write,
- free: kernel_free,
- lock: kernel_stream_lock,
- unlock: kernel_stream_unlock,
+ write: kernel_write,
+ free: kernel_free,
+ lock: kernel_stream_lock,
+ unlock: kernel_stream_unlock,
};
/** Shared state for kernel streams.
* shared state and avoid allocating it.
*/
static const KernelData kernel_data = {
- lock: SPIN_LOCK_UNLOCKED,
- flags: 0,
- buf_n: BUF_N,
+ lock: SPIN_LOCK_UNLOCKED,
+ flags: 0,
+ buf_n: BUF_N,
};
/** Stream for kernel printk. */
static IOStream iokernel = {
methods: &kernel_methods,
data: &kernel_data,
+ nofree: 1,
};
/** Stream for kernel printk. */
* @return kernel stream
*/
IOStream get_stream_kernel(void){
- return iokernel;
+ return iokernel;
}
/** Obtain the lock on the stream state.
* @param kdata stream state
*/
static inline void KernelData_lock(KernelData *kdata){
- spin_lock_irqsave(&kdata->lock, kdata->flags);
+ spin_lock_irqsave(&kdata->lock, kdata->flags);
}
/** Release the lock on the stream state.
* @param kdata stream state
*/
static inline void KernelData_unlock(KernelData *kdata){
- spin_unlock_irqrestore(&kdata->lock, kdata->flags);
+ spin_unlock_irqrestore(&kdata->lock, kdata->flags);
}
/** Get the stream state.
* @return stream state
*/
static inline KernelData *get_kernel_data(IOStream *s){
- return (KernelData*)s->data;
+ return (KernelData*)s->data;
}
/** Obtain the lock on the stream state.
* @return result of the print
*/
static int kernel_write(IOStream *stream, const void *buf, size_t n){
- KernelData *kdata = get_kernel_data(stream);
- int k;
- k = kdata->buf_n - 1;
- if(n < k) k = n;
- memcpy(kdata->buf, buf, k);
- kdata->buf[k] = '\0';
- printk(kdata->buf);
- return k;
+ KernelData *kdata = get_kernel_data(stream);
+ int k;
+ k = kdata->buf_n - 1;
+ if(n < k) k = n;
+ memcpy(kdata->buf, buf, k);
+ kdata->buf[k] = '\0';
+ printk(kdata->buf);
+ return k;
}
/** Free a kernel stream.
* @param io stream to free
*/
static void kernel_free(IOStream *io){
- KernelData *kdata;
- if(io == &iokernel) return;
- kdata = get_kernel_data(io);
- memset(kdata, 0, sizeof(*kdata));
- deallocate(kdata);
+ KernelData *kdata;
+ if(io == &iokernel) return;
+ kdata = get_kernel_data(io);
+ memset(kdata, 0, sizeof(*kdata));
+ deallocate(kdata);
}
#endif /* __KERNEL__ */
static int string_error(IOStream *io);
static int string_close(IOStream *io);
static void string_free(IOStream *io);
+static int string_write(IOStream *io, const void *msg, size_t n);
+static int string_read(IOStream *io, void *buf, size_t n);
/** Methods for a string stream. */
static IOMethods string_methods = {
- //print: string_print,
- //getc: string_getc,
+ read: string_read,
+ write: string_write,
error: string_error,
close: string_close,
free: string_free,
return (StringData*)io->data;
}
+static int string_write(IOStream *io, const void *msg, size_t n){
+ StringData *data = get_string_data(io);
+ int k;
+
+ k = data->end - data->out;
+ if(n > k) n = k;
+ memcpy(data->out, msg, n);
+ data->out += n;
+ return n;
+}
+
+static int string_read(IOStream *io, void *buf, size_t n){
+ StringData *data = get_string_data(io);
+ int k;
+
+ k = data->end - data->in;
+ if(n > k) n = k;
+ memcpy(buf, data->in, k);
+ data->in += n;
+ return n;
+}
+
/** Test if a string stream has an error.
*
* @param io string stream
}
/** Free a string stream.
- * The stream must have been allocated, not statically created.
* The stream state is freed, but the underlying string is not.
*
* @param io string stream
}
/** Initialise a string stream, usually from static data.
+ * If the stream and StringData should be freed when
+ * the stream is closed, unset io->nofree.
+ * The string is not freed on close.
*
* @param io address of IOStream to fill in
* @param data address of StringData to fill in
memzero(io, sizeof(*io));
io->methods = &string_methods;
io->data = data;
+ io->nofree = 1;
}
}
/** Allocate and initialise a string stream.
+ * The stream is freed on close, but the string is not.
*
* @param s string to use
* @param n length of the string
if(data && io){
ok = 1;
string_stream_init(io, data, s, n);
+ io->nofree = 0;
}
if(!ok){
deallocate(data);
+++ /dev/null
-#ifndef _XFRD_HTTP_H_
-#define _XFRD_HTTP_H_
-
-enum {
- HTTP_OK = 200,
- HTTP_CREATED = 201,
- HTTP_ACCEPTED = 202,
- HTTP_NON_AUTHORITATIVE_INFORMATION = 203,
- HTTP_NO_CONTENT = 204,
- HTTP_RESET_CONTENT = 205,
- HTTP_PARTIAL_CONTENT = 206,
- HTTP_MULTI_STATUS = 207,
-
- HTTP_MULTIPLE_CHOICE = 300,
- HTTP_MOVED_PERMANENTLY = 301,
- HTTP_FOUND = 302,
- HTTP_SEE_OTHER = 303,
- HTTP_NOT_MODIFIED = 304,
- HTTP_USE_PROXY = 305,
- HTTP_TEMPORARY_REDIRECT = 307,
-
- HTTP_BAD_REQUEST = 400,
- HTTP_UNAUTHORIZED = 401,
- HTTP_PAYMENT_REQUIRED = 402,
- HTTP_FORBIDDEN = 403,
- HTTP_NOT_FOUND = 404,
- HTTP_NOT_ALLOWED = 405,
- HTTP_NOT_ACCEPTABLE = 406,
- HTTP_PROXY_AUTH_REQUIRED = 407,
- HTTP_REQUEST_TIMEOUT = 408,
- HTTP_CONFLICT = 409,
- HTTP_GONE = 410,
- HTTP_LENGTH_REQUIRED = 411,
- HTTP_PRECONDITION_FAILED = 412,
- HTTP_REQUEST_ENTITY_TOO_LARGE = 413,
- HTTP_REQUEST_URI_TOO_LONG = 414,
- HTTP_UNSUPPORTED_MEDIA_TYPE = 415,
- HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416,
- HTTP_EXPECTATION_FAILED = 417,
-
- HTTP_INTERNAL_SERVER_ERROR = 500,
- HTTP_NOT_IMPLEMENTED = 501,
- HTTP_BAD_GATEWAY = 502,
- HTTP_SERVICE_UNAVAILABLE = 503,
- HTTP_GATEWAY_TIMEOUT = 504,
- HTTP_VERSION_NOT_SUPPORTED = 505,
- HTTP_INSUFFICIENT_STORAGE_SPACE = 507,
- HTTP_NOT_EXTENDED = 510,
-};
-#endif /* ! _XFRD_HTTP_H_ */
+++ /dev/null
-#include <errno.h>
-#include "xdr.h"
-
-#define MODULE_NAME "XDR"
-//#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** @file
- * XDR packer/unpacker for elements.
- *
- * string -> [T_STRING] [len:u16] <len bytes>
- * atom -> [T_ATOM] [len:u16] <len bytes>
- * uint -> [T_UINT] [value]
- * cons -> [T_LIST] {1 elt}* 0
- * null -> [T_NULL]
- * none -> [T_NONE]
- * bool -> [T_BOOL] { 0:u8 | 1:u8 }
- *
- * types packed as u16.
- *
- * So (a b c) -> [T_CONS] a [T_CONS] b [T_CONS] c [T_NULL]
- * () -> [T_NULL]
- */
-
-int pack_bool(IOStream *io, int x){
- int err=0;
- //dprintf("> x=%d\n", x);
- err = IOStream_print(io, "%c", 0xff & x);
- if(err > 0) err = 0;
- //dprintf("< err=%d\n", err);
- return err;
-}
-
-int unpack_bool(IOStream *io, int *x){
- int err = 0;
- int c;
- //dprintf(">\n");
- c = IOStream_getc(io);
- *x = (c < 0 ? 0 : c);
- err = IOStream_error(io);
- if(c < 0 && !err) err = -EIO;
- //dprintf("< err=%d x=%d\n", err, *x);
- return err;
-}
-
-int pack_ushort(IOStream *io, unsigned short x){
- int err=0;
- //dprintf("> x=%u\n", x);
- err = IOStream_print(io, "%c%c",
- 0xff & (x >> 8),
- 0xff & (x ));
- if(err > 0) err = 0;
- //dprintf("< err=%d\n", err);
- return err;
-}
-
-int unpack_ushort(IOStream *io, unsigned short *x){
- int err = 0;
- int i, c = 0;
- //dprintf(">\n");
- *x = 0;
- for(i = 0; i< 2; i++){
- c = IOStream_getc(io);
- if(c < 0) break;
- *x <<= 8;
- *x |= (0xff & c);
- }
- err = IOStream_error(io);
-
- if(c < 0 && !err) err = -EIO;
- //dprintf("< err=%d x=%u\n", err, *x);
- return err;
-}
-
-int pack_type(IOStream *io, unsigned short x){
- return pack_ushort(io, x);
-}
-
-int unpack_type(IOStream *io, unsigned short *x){
- return unpack_ushort(io, x);
-}
-
-int pack_uint(IOStream *io, unsigned int x){
- int err=0;
- //dprintf("> x=%u\n", x);
- err = IOStream_print(io, "%c%c%c%c",
- 0xff & (x >> 24),
- 0xff & (x >> 16),
- 0xff & (x >> 8),
- 0xff & (x ));
- if(err > 0) err = 0;
- //dprintf("< err=%d\n", err);
- return err;
-}
-
-int unpack_uint(IOStream *io, unsigned int *x){
- int err = 0;
- int i, c = 0;
- //dprintf(">\n");
- *x = 0;
- for(i = 0; i< 4; i++){
- c = IOStream_getc(io);
- if(c < 0) break;
- *x <<= 8;
- *x |= (0xff & c);
- }
- err = IOStream_error(io);
- if(c < 0 && !err) err = -EIO;
- //dprintf("< err=%d x=%u\n", err, *x);
- return err;
-}
-
-int pack_string(IOStream *io, Sxpr x){
- int err = 0;
- unsigned short n = 0xffff & string_length(x);
- char *s = string_string(x);
- int i;
- //dprintf("> n=%d s=%s\n", n, s);
- err = pack_ushort(io, n);
- if(err) goto exit;
- for(i = 0; i < n; i++){
- err = IOStream_print(io, "%c", s[i]);
- if(err < 0) break;
- }
- if(err > 0) err = 0;
- exit:
- //dprintf("< err=%d\n", err);
- return err;
-}
-
-int unpack_string(IOStream *io, Sxpr *x){
- int err;
- unsigned short n;
- int i, c = 0;
- char *s;
- Sxpr val = ONONE;
-
- //dprintf(">\n");
- err = unpack_ushort(io, &n);
- if(err) goto exit;
- val = halloc(n+1, T_STRING);
- if(NOMEMP(val)){
- err = -ENOMEM;
- goto exit;
- }
- s = string_string(val);
- for(i=0; i<n; i++){
- c = IOStream_getc(io);
- if(c < 0) break;
- s[i] = (char)c;
- }
- s[n] = '\0';
- exit:
- err = IOStream_error(io);
- if(c < 0 && !err) err = -EIO;
- if(err){
- objfree(val);
- val = ONONE;
- }
- *x = val;
- //IOStream_print(iostdout, "n=%d str=", n);
- //objprint(iostdout, *x, 0);
- //IOStream_print(iostdout, "\n");
- //dprintf("< err=%d\n", err);
- return err;
-}
-
-int pack_cons(IOStream *io, Sxpr x){
- int err = 0;
- Sxpr l;
- //dprintf(">\n");
- for(l = x; CONSP(l); l = CDR(l)){
- err = pack_bool(io, 1);
- if(err) goto exit;
- err = pack_sxpr(io, CAR(l));
- if(err) goto exit;
- }
- err = pack_bool(io, 0);
- exit:
- //dprintf("< err=%d\n", err);
- return err;
-}
-
-int unpack_cons(IOStream *io, Sxpr *x){
- int err = 0;
- int more = 0;
- Sxpr u = ONONE, v = ONONE, val = ONULL;
-
- dprintf(">\n");
- while(1){
- err = unpack_bool(io, &more);
- if(err) goto exit;
- if(!more){
- //IOStream_print(iostdout, "unpack_cons 1 val=");
- ////objprint(iostdout, val, 0);
- IOStream_print(iostdout, "\n");
-
- val = nrev(val);
-
- //IOStream_print(iostdout, "unpack_cons 2 val=");
- //objprint(iostdout, val, 0);
- //IOStream_print(iostdout, "\n");
-
- break;
- }
- err = unpack_sxpr(io, &u);
- if(err) goto exit;
- v = cons_new(u, val);
- if(NOMEMP(v)){
- err = -ENOMEM;
- objfree(u);
- goto exit;
- }
- val = v;
- }
- exit:
- if(err){
- objfree(val);
- val = ONONE;
- }
- *x = val;
- dprintf("< err=%d\n", err);
- return err;
-}
-
-int pack_sxpr(IOStream *io, Sxpr x){
- int err = 0;
- unsigned short type = get_type(x);
- //dprintf(">\n");
- //objprint(iostdout, x, 0);
- //IOStream_print(iostdout, "\n");
-
- err = pack_type(io, type);
- if(err) goto exit;
- switch(type){
- case T_NULL:
- break;
- case T_NONE:
- break;
- case T_BOOL:
- err = pack_bool(io, get_ul(x));
- break;
- case T_CONS:
- err = pack_cons(io, x);
- break;
- case T_ATOM:
- err = pack_string(io, OBJ_ATOM(x)->name);
- break;
- case T_STRING:
- err = pack_string(io, x);
- break;
- case T_UINT:
- err = pack_uint(io, get_ul(x));
- break;
- default:
- err = -EINVAL;
- IOStream_print(iostderr, "%s> invalid type %d\n", __FUNCTION__, type);
- break;
- }
- exit:
- //dprintf("< err=%d\n", err);
- return err;
-}
-
-int unpack_sxpr(IOStream *io, Sxpr *x){
- int err = 0;
- unsigned short type;
- unsigned int u;
- Sxpr val = ONONE, y;
-
- //dprintf(">\n");
- err = unpack_type(io, &type);
- if(err) goto exit;
- switch(type){
- case T_NULL:
- val = ONULL;
- break;
- case T_NONE:
- val = ONONE;
- break;
- case T_CONS:
- err = unpack_cons(io, &val);
- break;
- case T_BOOL:
- err = unpack_bool(io, (int *)&u);
- if(err) goto exit;
- val = (u ? OTRUE : OFALSE);
- break;
- case T_ATOM:
- err = unpack_string(io, &y);
- if(err) goto exit;
- val = intern(string_string(y));
- objfree(y);
- break;
- case T_STRING:
- err = unpack_string(io, &val);
- break;
- case T_UINT:
- err = unpack_uint(io, &u);
- if(err) goto exit;
- val = OBJI(type, u);
- break;
- default:
- err = -EINVAL;
- IOStream_print(iostderr, "%s> invalid type %d\n", __FUNCTION__, type);
- break;
- }
- exit:
- *x = (err ? ONONE : val);
- //IOStream_print(iostdout, "sxpr=");
- //objprint(iostdout, *x, 0);
- //IOStream_print(iostdout, "\n");
- //dprintf("< err=%d\n", err);
- return err;
-}
+++ /dev/null
-#ifndef _XUTIL_XDR_H_
-#define _XUTIL_XDR_H_
-#include "iostream.h"
-#include "sxpr.h"
-
-int pack_type(IOStream *io, unsigned short x);
-
-int unpack_type(IOStream *io, unsigned short *x);
-
-int pack_bool(IOStream *io, int x);
-
-int unpack_bool(IOStream *io, int *x);
-
-int pack_uint(IOStream *out, unsigned int x);
-
-int unpack_uint(IOStream *in, unsigned int *x);
-
-int pack_string(IOStream *out, Sxpr x);
-
-int unpack_string(IOStream *in, Sxpr *x);
-
-int pack_cons(IOStream *out, Sxpr x);
-
-int unpack_cons(IOStream *in, Sxpr *x);
-
-int pack_sxpr(IOStream *out, Sxpr x);
-
-int unpack_sxpr(IOStream *in, Sxpr *x);
-
-#endif /* _XUTIL_XDR_H_ */